package com.citcc.api.controller;

import com.citcc.api.config.Authorization;
import com.citcc.api.netty.utils.CommandUtil;
import com.citcc.business.bean.*;
import com.citcc.business.bean.dto.CdzDto;
import com.citcc.business.bean.vo.CdzOrderVo;
import com.citcc.business.bean.vo.SsDLVo;
import com.citcc.business.service.CdzAppUserService;
import com.citcc.business.service.ScanCodeService;
import com.citcc.business.util.CollectionUtil;
import com.citcc.common.base.AjaxResult;
import com.citcc.common.jpush.PushUtil;
import com.citcc.common.utils.DateUtils;
import com.citcc.common.utils.StringUtils;
import com.citcc.framework.base.BaseController;
import com.citcc.system.bean.SysDictData;
import com.citcc.system.service.impl.SysDictDataServiceImpl;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.ibatis.session.RowBounds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: qinbo
 * Date: 2019/4/5
 * Time: 16:49
 * Description: 扫码充电相关接口
 */
@Api(tags = "扫码充电相关")
@RestController
public class ScanCodeController extends BaseController {
    private Logger logger = LoggerFactory.getLogger(ScanCodeController.class);
    @Autowired
    private ScanCodeService scanCodeService;

    @Autowired
    private SysDictDataServiceImpl sysDictDataService;
    @Autowired
    private CdzAppUserService cdzAppUserService;

    /**
     * DecimalFormat 内部静态方法较多，设置单例
     */
    private static class DecimalFormatProvider {
        private static final DecimalFormat format = new DecimalFormat("#,##0.00");
    }

    public static DecimalFormat getFormat() {
        return DecimalFormatProvider.format;
    }

    /**
     * 订单列表 0:全部 1，充电中，2，已完成
     *
     * @param user
     * @param type
     * @return
     */
    @ApiOperation("订单列表 type 0:全部 1，充电中，2，已完成，3.关闭 4结束中")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "type", value = "0:全部 1，充电中，2，已完成，3.关闭", paramType = "query"),
            @ApiImplicitParam(name = "offset", value = "页数", paramType = "query"),
            @ApiImplicitParam(name = "limit", value = "每页条数", paramType = "query")
    })
    @RequestMapping(value = "/v1/api/order/msgs", method = RequestMethod.POST)
    public AjaxResult userOrder(@Authorization CdzAppUser user, @RequestParam(name = "type", defaultValue = "0") String type,
                                @RequestParam(name = "offset", defaultValue = "0") Integer offset,
                                @RequestParam(name = "limit", defaultValue = "10") Integer limit
    ) {
        logger.info("订单列表===" + type);
        //startPage();
        RowBounds rowBounds = new RowBounds(offset, limit);
        List<UserOrderEntity> list = scanCodeService.getOrderList(user.getId(), type, rowBounds);
        List<CdzOrderVo> vos = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(list)) {
            for (UserOrderEntity userOrderEntity : list) {
                CdzOrderVo cdzOrderVo = new CdzOrderVo();
                cdzOrderVo.setCdzName(userOrderEntity.getStationName());
                //枪号获取字典标签
                String gunNum = sysDictDataService.selectDictLabel("gun_code", userOrderEntity.getGunCode());
                cdzOrderVo.setGunNum(gunNum);
                cdzOrderVo.setStakeCode(userOrderEntity.getStakeCode());
                cdzOrderVo.setChargeType(userOrderEntity.getChargeType());
                cdzOrderVo.setStandard(userOrderEntity.getChargeStandard());
                cdzOrderVo.setPower(userOrderEntity.getChargePower());
                cdzOrderVo.setDy(userOrderEntity.getChargeDy());
                cdzOrderVo.setCdf(getFormat().format(userOrderEntity.getChargeMoney()));
                cdzOrderVo.setFwf(getFormat().format(userOrderEntity.getChargeFw()));
                cdzOrderVo.setTcf(getFormat().format(userOrderEntity.getChargeTc()));
                //充电模式获取字典标签
                String chargeMs = sysDictDataService.selectDictLabel("charge_ms", userOrderEntity.getChargeMs());
                cdzOrderVo.setMs(chargeMs);
                cdzOrderVo.setChargeLong(userOrderEntity.getChargeLong() + "");
                cdzOrderVo.setCddl(userOrderEntity.getChargeDn());
                String payState = StringUtils.isEmpty(userOrderEntity.getPayState()) ? "other" : userOrderEntity.getPayState();
                switch (payState) {
                    case "0":
                        cdzOrderVo.setPayState("未完成");
                        break;
                    case "1":
                        cdzOrderVo.setPayState("未完成");
                        break;
                    case "2":
                        cdzOrderVo.setPayState("支付完成");
                        break;
                    default:
                        cdzOrderVo.setPayState("未完成");
                        break;
                }
                if (userOrderEntity.getStartTime() != null) {
                    cdzOrderVo.setStartTime(DateUtils.formatDate2Str(1, userOrderEntity.getStartTime()));
                }
                if (userOrderEntity.getEndTime() != null) {
                    cdzOrderVo.setEndTime(DateUtils.formatDate2Str(1, userOrderEntity.getEndTime()));
                }
                String payType = StringUtils.isEmpty(userOrderEntity.getPayType()) ? "other" : userOrderEntity.getPayType();
                //支付类型获取字典标签
                String payName = sysDictDataService.selectDictLabel("station_payType", payType);
                cdzOrderVo.setPayType(payName);
                cdzOrderVo.setCdzId(userOrderEntity.getId());
                if (userOrderEntity.getCreateTime() != null) {//原来是payTime，改为createTime
                    cdzOrderVo.setPayTime(DateUtils.formatDate2Str(1, userOrderEntity.getCreateTime()));
                }
                cdzOrderVo.setChargeState(userOrderEntity.getChargeState());
                if ("0".equals(userOrderEntity.getChargeState()) || "4".equals(userOrderEntity.getChargeState())){//充电中,结束中
                    cdzOrderVo.setCdfy("");
                }else if ("2".equals(userOrderEntity.getChargeState()) || "3".equals(userOrderEntity.getChargeState())){//已完成,关闭
                    if (null != userOrderEntity.getPayNumberPlan()){
                        cdzOrderVo.setCdfy(getFormat().format(userOrderEntity.getPayNumberPlan()) + "元");
                    }else{
                        cdzOrderVo.setCdfy("0.00元");
                    }
                }
                vos.add(cdzOrderVo);
            }
        }
        logger.info(vos + "");
        return success(200, vos);
    }

    /**
     * 充电详情 0:全部 1，充电中，2，已完成 3:关闭 4结束中
     *
     * @param user
     * @return
     */
    @ApiOperation("充电详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderNum", value = "订单编号", paramType = "query"),
    })
    @RequestMapping(value = "/v1/api/order/detail", method = RequestMethod.POST)
    public AjaxResult getDetail(@Authorization CdzAppUser user, @RequestParam String orderNum
    ) {
        startPage();
        UserOrderEntity userOrderEntity = scanCodeService.getCdOrder(orderNum);
        if (userOrderEntity == null) {
            return error(-1, "未查到相关订单信息");
        }
        CdzOrderVo cdzOrderVo = new CdzOrderVo();
        cdzOrderVo.setCdzName(StringUtils.isEmpty(userOrderEntity.getStationName()) ? "充电桩" : userOrderEntity.getStationName());
        //枪号获取字典标签
        String gunNum = sysDictDataService.selectDictLabel("gun_code", userOrderEntity.getGunCode());
        cdzOrderVo.setGunNum(gunNum);
        //结束方式获取字典标签
        String endTypeName = sysDictDataService.selectDictLabel("end_type", userOrderEntity.getEndType());
        cdzOrderVo.setEndType(endTypeName);
        String stakeCode = userOrderEntity.getStakeCode();
        cdzOrderVo.setStakeCode(stakeCode);
        if (StringUtils.isNotEmpty(stakeCode)){
            CdzStake cdzStakeBycode = scanCodeService.getCdzStakeBycode(stakeCode);
            if (cdzStakeBycode!=null){
                String num = cdzStakeBycode.getNum();
                cdzOrderVo.setStakeNum(num);
            }else {
                logger.info(stakeCode+"桩编号为null");
                cdzOrderVo.setStakeNum(null);
            }
        }else {
            logger.info(stakeCode+"桩编号为null");
            cdzOrderVo.setStakeNum(null);
        }


        String type = StringUtils.isEmpty(userOrderEntity.getChargeType()) ? "other" : userOrderEntity.getChargeType();
        switch (type) {
            case "1":
                cdzOrderVo.setChargeType("直流");
                break;
            case "2":
                cdzOrderVo.setChargeType("交流");
                break;
            case "3":
                cdzOrderVo.setChargeType("混合");
                break;
            default:
                cdzOrderVo.setChargeType("直流");
                break;
        }
        String payType = StringUtils.isEmpty(userOrderEntity.getPayType()) ? "other" : userOrderEntity.getPayType();
        logger.info(payType);
        //支付类型获取字典标签
        String payName = sysDictDataService.selectDictLabel("station_payType", payType);
        cdzOrderVo.setPayType(payName);
        logger.info("cdzOrderVo" + cdzOrderVo);

        String payState = StringUtils.isEmpty(userOrderEntity.getPayState()) ? "other" : userOrderEntity.getPayState();
        switch (payState) {
            case "0":
                cdzOrderVo.setPayState("未完成");
                break;
            case "1":
                cdzOrderVo.setPayState("未完成");
                break;
            case "2":
                cdzOrderVo.setPayState("支付完成");
                break;
            default:
                cdzOrderVo.setPayState("未完成");
                break;
        }
        //充电模式获取字典标签
        String chargeMs = sysDictDataService.selectDictLabel("charge_ms", userOrderEntity.getChargeMs());
        //模式名称
        cdzOrderVo.setMs(chargeMs);
        //模式值
        cdzOrderVo.setChargeMs(userOrderEntity.getChargeMs());
        //充电模式（0-自动充满，1-按金额充电，2-按时间充电，3-按电量充电）
        switch (userOrderEntity.getChargeMs()){
            case "1":
                //所选的值
                cdzOrderVo.setValue(userOrderEntity.getValue() + "元");
                break;
            case "2":
                //所选的值
                cdzOrderVo.setValue(userOrderEntity.getValue() + "小时");
                break;
            case "3":
                //所选的值
                cdzOrderVo.setValue(userOrderEntity.getValue() + "度");
                break;
        }
        cdzOrderVo.setStandard(userOrderEntity.getChargeStandard());
        cdzOrderVo.setPower(StringUtils.isEmpty(userOrderEntity.getChargePower()) ? "0KW" : userOrderEntity.getChargePower());
        cdzOrderVo.setDy(StringUtils.isEmpty(userOrderEntity.getChargeDy()) ? "0V" : userOrderEntity.getChargeDy());
        cdzOrderVo.setCdf(getFormat().format(userOrderEntity.getChargeMoney()) + "元/度");
        cdzOrderVo.setFwf(getFormat().format(userOrderEntity.getChargeFw()) + "元/度");
        cdzOrderVo.setTcf(getFormat().format(userOrderEntity.getChargeTc()) + "元/小时");
        if (userOrderEntity.getChargeLong() != null) {
            long l = userOrderEntity.getChargeLong().longValue();
            String s = DateUtils.millisToStringShortCN(l * 1000);
            cdzOrderVo.setChargeLong(s + "");
        } else {
            cdzOrderVo.setChargeLong("");
        }
        if (userOrderEntity.getStartTime() != null) {
            cdzOrderVo.setStartTime(DateUtils.formatDate2Str(1, userOrderEntity.getStartTime()));
        }
        if (userOrderEntity.getEndTime() != null) {
            cdzOrderVo.setEndTime(DateUtils.formatDate2Str(1, userOrderEntity.getEndTime()));
        }
        cdzOrderVo.setCdzId(userOrderEntity.getId());
        cdzOrderVo.setChargeState(userOrderEntity.getChargeState());

        cdzOrderVo.setCddl(StringUtils.isEmpty(userOrderEntity.getChargeDn()) ? "0度" : userOrderEntity.getChargeDn() + "度");

        if ("0".equals(userOrderEntity.getChargeState())){
            //充电中
            //cdzOrderVo.setTkCdfy(getFormat().format(userOrderEntity.getPayNumber())+"元");
        }else if ("2".equals(userOrderEntity.getChargeState())){//已完成
                if ("1".equals(user.getUserType())){//内部客户
                    cdzOrderVo.setTk(true);
                    if (null != userOrderEntity.getPayNumberPlan()){//实际充电费用
                        cdzOrderVo.setCdfy(getFormat().format(userOrderEntity.getPayNumberPlan()) + "元");
                    }else{
                        cdzOrderVo.setCdfy("0.00元");
                    }
                    if (null != userOrderEntity.getMoney()){//实付金额
                        cdzOrderVo.setMoney(getFormat().format(userOrderEntity.getMoney())+"元");
                    }else{
                        cdzOrderVo.setMoney("0.00元");
                    }
                    if (null != userOrderEntity.getOffMoney()){//优惠金额
                        cdzOrderVo.setOffMoney(getFormat().format(userOrderEntity.getOffMoney()) + "元");
                    }else{
                        cdzOrderVo.setOffMoney("0.00元");
                    }
                    //优惠方式
                    cdzOrderVo.setOffType(userOrderEntity.getOffType());
                }else{//普通客户
                    //是否显示优惠方式
                    cdzOrderVo.setTk(false);
                    if (null != userOrderEntity.getPayNumberPlan()){
                        cdzOrderVo.setCdfy(getFormat().format(userOrderEntity.getPayNumberPlan())+"元");
                    }else{
                        cdzOrderVo.setCdfy("0.00元");
                    }
                }
        }else if ("3".equals(userOrderEntity.getChargeState())){//已关闭
            if (null != userOrderEntity.getPayNumberPlan()){
                cdzOrderVo.setCdfy(getFormat().format(userOrderEntity.getPayNumberPlan())+"元");
            }else{
                cdzOrderVo.setCdfy("0.00元");
            }
        }
        logger.info(cdzOrderVo + "");
        return success(200, cdzOrderVo);
    }
    /**
     * 判断充电桩是否可以用
     *
     * @param cdzDto
     * @return
     */
    /**
     * @return
     */
    @ApiOperation("判断充电枪是否可以用")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "cdqNum", value = "枪编号", paramType = "query"),
            @ApiImplicitParam(name = "cdzNum", value = "唯一编号", paramType = "query"),
    })
    @RequestMapping(value = "/v3/api/cqz/state", method = RequestMethod.POST)
    public AjaxResult control(CdzDto cdzDto) {
        logger.info("cdzDto" + cdzDto);
        CdzGun cdzGun = scanCodeService.checkCdzGun(cdzDto.getCdqNum(), cdzDto.getCdzNum());
        if (cdzGun == null) {
            logger.info("未查询到对应充电枪");
            return error(-1, "未查询到对应充电枪");
        }
        if (!"2".equals(cdzGun.getStatus())) {
            logger.info("未查询到对应充电枪" + cdzGun.getStatus());
            return error(-1, "该充电枪不可用");
        }
        return success(200);
    }

    @ApiOperation("结束充电")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "cdqNum", value = "枪编号", paramType = "query"),
    })
    @RequestMapping(value = "/v1/api/cqz/end", method = RequestMethod.POST)
    public AjaxResult endCharge(@Authorization CdzAppUser cdzAppUser, CdzDto cdzDto) {
        //调用充电指令
        UserOrderEntity cdOrder = scanCodeService.getCdOrder(cdzDto.getOrderNum());
        if (cdOrder == null) {
            return error(-1, "未查询到相关信息");
        }
        //小于两分钟提示：绝缘检测中不能结束充电
        CdzChargingEntity cdzChargingEntity = scanCodeService.getDL(cdzDto.getOrderNum());
        String time = cdzChargingEntity.getTime();
        if (StringUtils.isEmpty(time)){
            return error(-1,"绝缘检测中不能结束充电");
        }else {
            if (Long.parseLong(time)>40){
                //判断状态是否充电中，充电中调用停止指令 else -1 充电已完成
                if ("0".equals(cdOrder.getChargeState())){
                    int cmd = CommandUtil.tcmd(cdOrder.getStakeCode(), cdOrder.getGunCode(), cdzAppUser.getPhone());
                    logger.info("结束充电，结果===" + cmd);
                    //如果是200 改状态结束中。 else -1 结束充电失败
                    if (200 == cmd){
                        cdOrder.setChargeState("4");
                        scanCodeService.updateUserOrderEntityById(cdOrder);
                        //推送消息到app
                        CdzAppUser user = cdzAppUserService.selectByPrimaryKey(cdOrder.getUserId());
                        List<Object> registrationIdList = new ArrayList<>();
                        if (StringUtils.isNotEmpty(user.getDeviceId())) {
                            logger.info("推送消息到app===" + user.getDeviceId());
                            registrationIdList.add(user.getDeviceId());
                            String title = "订单状态改变";
                            String body = "推送消息到app";
                            try {
                                PushUtil.messagePush(registrationIdList, title, body, "1", "", user.getType());
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }else{
                        return error(-1,"结束充电失败");
                    }
                }else{
                    return error(-1,"充电已完成");
                }
                return success(200);
            }
            return error(-1,"绝缘检测中不能结束充电");
        }
    }

    @ApiOperation("查看充电电量")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "cdqNum", value = "枪编号", paramType = "query"),
    })
    @RequestMapping(value = "/v1/api/cd/msg", method = RequestMethod.POST)
    public AjaxResult getCharge(CdzDto cdzDto) {
        logger.info("cdzz");
        //调用充电指令
        CdzChargingEntity cdzChargingEntity = scanCodeService.getDL(cdzDto.getOrderNum());
        if (cdzChargingEntity == null) {
            return error(-1, "未查询到相关信息");
        }
        UserOrderEntity cdOrder = scanCodeService.getCdOrder(cdzDto.getOrderNum());
        if (cdOrder == null) {
            return error(-1, "订单不存在");
        }
        //充电状态 已完成或者关闭 返回-1，提示语
        if ("2".equals(cdOrder.getChargeState()) || "3".equals(cdOrder.getChargeState())){
            return error(-1, "订单已完成或关闭");
        }

        SsDLVo ssDLVo = new SsDLVo();
        ssDLVo.setDl(cdzChargingEntity.getSoc());
        if (StringUtils.isNotEmpty(cdzChargingEntity.getSyTime())) {
            long l = Long.parseLong(cdzChargingEntity.getSyTime());
            String s = DateUtils.millisToStringShort(l);
            ssDLVo.setSysj(s);
        } else {
            String s = DateUtils.millisToStringShort(0);
            ssDLVo.setSysj(s);
        }
        ssDLVo.setYcdl(StringUtils.isEmpty(cdzChargingEntity.getDn()) ? "0度" : cdzChargingEntity.getDn() + "度");

        if (StringUtils.isNotEmpty(cdzChargingEntity.getTime())) {
            long l = Long.parseLong(cdzChargingEntity.getTime());
            String s = DateUtils.millisToStringShort(l * 1000);
            ssDLVo.setYcsc(s);
        } else {
            ssDLVo.setYcsc(null);
        }

        if (StringUtils.isNotEmpty(cdzChargingEntity.getFullTime())) {
            long l = Long.parseLong(cdzChargingEntity.getFullTime());
            String s = DateUtils.millisToStringShort(l * 60 * 1000);
            ssDLVo.setFullTime(s);
        } else {
            ssDLVo.setFullTime("--:--:--");
        }
        ssDLVo.setSyMoney(getFormat().format(cdzChargingEntity.getSyMoney()) + "元");
        ssDLVo.setUsingMoney(getFormat().format(cdzChargingEntity.getUsingMoney()) + "元");
        return success(200, ssDLVo);
    }

    @ApiOperation("获取充电模式")
    @RequestMapping(value = "/v1/api/getChargeMs", method = RequestMethod.GET)
    public AjaxResult getChargeMs(){
        List<SysDictData> list = sysDictDataService.selectDictDataByType("charge_ms");
        return success(200,list);
    }

}